/*-------------------------------------------------------------------------
 *
 * htup.h
 *	  POSTGRES 堆元组的定义
 *
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/access/htup.h
 *
 *-------------------------------------------------------------------------
 */
#ifndef HTUP_H
#define HTUP_H

#include "storage/itemptr.h"

/* 在 htup_details.h 中定义的结构体的 typedef 和前向声明 */

typedef struct HeapTupleHeaderData HeapTupleHeaderData;

typedef HeapTupleHeaderData *HeapTupleHeader;

typedef struct MinimalTupleData MinimalTupleData;

typedef MinimalTupleData *MinimalTuple;



/*
 * HeapTupleData 是一个指向元组的内存数据结构。
 *
 * 该数据结构有几种使用方式：
 *
 * * 指向磁盘缓冲区中的元组：t_data 直接指向缓冲区（代码最好在此持有一个锁，但这在 HeapTupleData 本身并未反映）。
 *
 * * 指向空值：t_data 为 NULL。在某些函数中用作失败指示。
 *
 * * palloc'ed 元组的一部分：HeapTupleData 本身和元组形成一个单一的 palloc'ed 块。t_data 指向在 HeapTupleData 结构体后面的内存位置（在偏移量 HEAPTUPLESIZE 处）。这是 heap_form_tuple 和相关例程的输出格式。
 *
 * * 单独分配的元组：t_data 指向一个 palloc'ed 块，该块与 HeapTupleData 不相邻。（该情况已被弃用，因为与情况 #1 难以区分。它应仅在有限的上下文中使用，在此上下文中代码知道情况 #1 永远不会适用。）
 *
 * * 单独分配的最小元组：t_data 指向 MinimalTuple 开始之前 MINIMAL_TUPLE_OFFSET 字节。与之前的情况一样，通过检查不能区分与情况 #1；设置或销毁此表示的代码必须清楚其所做的事情。
 *
 * t_len 应始终有效，除非在指向空值的情况下。t_self 和 t_tableOid 应是有效的，如果 HeapTupleData 指向一个磁盘缓冲区，或如果它表示磁盘上元组的副本。它们应在制造的元组中显式设置为无效。
 */
typedef struct HeapTupleData
{
	uint32		t_len;			/* t_data 的长度 */
	ItemPointerData t_self;		/* SelfItemPointer */
	Oid			t_tableOid;		/* 元组来源的表 */
#define FIELDNO_HEAPTUPLEDATA_DATA 3
	HeapTupleHeader t_data;		/* -> 元组头和数据 */
} HeapTupleData;

typedef HeapTupleData *HeapTuple;

#define HEAPTUPLESIZE	MAXALIGN(sizeof(HeapTupleData))

/*
 * 访问器宏用于 HeapTuple 指针。
 */
#define HeapTupleIsValid(tuple) PointerIsValid(tuple)

/* HeapTupleHeader 函数在 utils/time/combocid.c 中实现 */
extern CommandId HeapTupleHeaderGetCmin(HeapTupleHeader tup);
extern CommandId HeapTupleHeaderGetCmax(HeapTupleHeader tup);
extern void HeapTupleHeaderAdjustCmax(HeapTupleHeader tup,
									  CommandId *cmax, bool *iscombo);

/* HeapTupleHeader 访问器的原型在 heapam.c 中 */
extern TransactionId HeapTupleGetUpdateXid(HeapTupleHeader tuple);

#endif							/* HTUP_H */
